/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.redPandaLib.core;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.redPandaLib.services.MessageVerifierHsqlDb;
import org.redPandaLib.services.MessageDownloader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.security.SecureRandom;
import java.sql.SQLTransactionRollbackException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.redPandaLib.ByteUtils;
import org.redPandaLib.Main;
import static org.redPandaLib.core.Test.getClonedPeerList;
import static org.redPandaLib.core.Test.peerList;
import static org.redPandaLib.core.Test.peerListLock;
import static org.redPandaLib.core.Test.saveTrustData;
import org.redPandaLib.core.messages.RawMsg;
import org.redPandaLib.crypt.AESCrypt;
import org.redPandaLib.crypt.ECKey;
import org.redPandaLib.crypt.RC4;
import org.redPandaLib.crypt.Sha256Hash;
import org.redPandaLib.crypt.Utils;
/**
*
* @author robin
*/
public class ConnectionHandler extends Thread {
public static final int READ_BUFFER_SIZE = 1024 * 205;
public Selector selector;
public static ArrayList<Socket> allSockets = new ArrayList<Socket>();
ExecutorService threadPool = new ThreadPoolExecutor(1, 3, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());//Executors.newFixedThreadPool(4);
ExecutorService threadPool2 = new ThreadPoolExecutor(1, 6, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());//Executors.newFixedThreadPool(4);
private boolean exit = false;
public static long lastRun = 0;
public static HashMap<ECKey, HashMap<PeerTrustData, Long>> ratingData = new HashMap<ECKey, HashMap<PeerTrustData, Long>>();
public ConnectionHandler() {
try {
selector = Selector.open();
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void exit() {
exit = true;
System.out.println("closing all connections....");
for (Peer peer : (ArrayList<Peer>) peerList.clone()) {
peer.disconnect("c");
}
System.out.println("Closing all associated channels...");
for (SelectionKey key : selector.keys()) {
try {
key.channel().close();
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
selector.wakeup();
System.out.println("Closing selector...");
try {
selector.close();
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
selector.wakeup();
interrupt();
}
public void addConnection(Peer peer, boolean connectionPending) {
synchronized (allSockets) {
allSockets.add(peer.getSocketChannel().socket());
}
//TODO: remove later when it will be saved...
//peer.keyToIdHis = new HashMap<Integer, ECKey>();
//peer.keyToIdMine = new ArrayList<Integer>();
peer.requestedMsgs = 0;
//peer.getPendingMessages().clear();//TODO muss weg, wenn das syncen richtig geht
peer.writeBufferLock.lock();
try {
peer.readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
peer.writeBuffer = ByteBuffer.allocate(1024 * 500);
} catch (Throwable e) {
System.out.println("Speicher konnte nicht reserviert werden. Disconnect peer...");
peer.disconnect("Speicher konnte nicht reserviert werden.");
} finally {
peer.writeBufferLock.unlock();
}
peer.firstCommandsProceeded = false;
peer.lastActionOnConnection = System.currentTimeMillis();
peer.setConnected(false);
peer.requestedNewAuth = false;
peer.authed = false;
peer.writeKey = null;
peer.readKey = null;
peer.writeBufferCrypted = null;
peer.readBufferCrypted = null;
peer.trustRetries = 0;
peer.removedSendMessages = new ArrayList<Integer>();
peer.maxSimultaneousRequests = 1;
peer.myInterestedChannelsCodedInHisIDs.clear();
try {
SocketChannel socketChannel = peer.getSocketChannel();
socketChannel.configureBlocking(false);
AbstractSelectableChannel socketC = socketChannel;
selector.wakeup();
//SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
SelectionKey key;
if (connectionPending) {
peer.isConnecting = true;
peer.setConnected(false);
key = socketC.register(selector, SelectionKey.OP_CONNECT);
} else {
peer.isConnecting = false;
peer.setConnected(true);
key = socketC.register(selector, SelectionKey.OP_READ);
}
key.attach(peer);
peer.setSelectionKey(key);
selector.wakeup();
//System.out.println("added con");
} catch (IOException ex) {
peer.disconnect("could not init connection....");
return;
}
sendHeader(peer);
}
@Override
public void run() {
final String orgName = Thread.currentThread().getName();
if (!orgName.contains(" ")) {
Thread.currentThread().setName(orgName + " - IncomingHandler - Main");
}
while (!Main.shutdown && !exit) {
lastRun = System.currentTimeMillis();
Log.put("NEW KEY RUN - before select", 2000);
int readyChannels = 0;
try {
readyChannels = selector.select();
} catch (Exception e) {
e.printStackTrace();
//Main.sendBroadCastMsg("key was canceled...");
try {
sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
continue;
}
Log.put("NEW KEY RUN - after select", 2000);
// try {
// for (SelectionKey sk : selector.keys()) {
// Peer peer = (Peer) sk.attachment();
// if (peer == null) {
// continue;
// }
// if (peer.selectionKey != sk) {
// System.out.println("key was replaced.... - have to cancel key...");
// }
// if (!Test.peerList.contains(peer)) {
// System.out.println("Peer was removed! - have to cancel key...");
// }
// }
// } catch (ConcurrentModificationException e) {
//
// }
//System.out.println("" + selector.isOpen() + " " + selector.keys().size());
Set<SelectionKey> selectedKeys = selector.selectedKeys();
if (readyChannels == 0 && selectedKeys.isEmpty()) {
// System.out.print(".");
// for (SelectionKey k : selector.keys()) {
//
//
// System.out.println("readyops: " + k.isAcceptable() + k.isConnectable() + k.isReadable() + k.isValid() + k.isWritable());
//
// if (k.readyOps() != 0) {
// k.cancel();
// }
//
// }
try {
sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
continue;
}
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
if (exit) {
break;
}
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (!key.isValid()) {
System.out.println("hmmm");
key.cancel();
//keyIterator.remove();
continue;
}
try {
if (key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
Log.put("incoming connection...", 12);
ServerSocketChannel s = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = s.accept();
socketChannel.configureBlocking(false);
String ip = socketChannel.socket().getInetAddress().getHostAddress();
//System.out.println("IPS: " + socketChannel.socket().getInetAddress().getCanonicalHostName());
Peer peer1 = new Peer(ip, 0);
peer1.setSocketChannel(socketChannel);
addConnection(peer1, false);
// System.out.println("from ip: " + ip);
// SelectionKey newKey = socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
// key.attach(peer);
Test.NAT_OPEN = true;
continue;
}
Peer peer = (Peer) key.attachment();
if (peer == null) {
key.cancel();
continue;
}
ByteBuffer readBuffer = peer.readBuffer;
ByteBuffer writeBuffer = peer.writeBuffer;
if (!key.isValid()) {
peer.disconnect("key is invalid.");
continue;
}
if (key.isConnectable()) {
//System.out.println("dwdhjawdgawgd ");
boolean connected = false;
try {
connected = peer.getSocketChannel().finishConnect();
} catch (IOException e) {
} catch (SecurityException e) {
}
// System.out.println("finished!");
if (!connected) {
Log.put("connection could not be established...", 150);
key.cancel();
peer.setConnected(false);
peer.isConnecting = false;
peer.getSocketChannel().close();
continue;
}
//System.out.println("Connection established...");
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
peer.isConnecting = false;
peer.setConnected(true);
// a connection was established with a remote server.
} else if (key.isReadable()) {
// System.out.println("readable " + key.isValid());
//int read = peer.getSocketChannel().read(peer.readBuffer);
// System.out.println("ffffffff" + peer.readBuffer.toString());
int read = -2;
if (peer.readBufferCrypted == null) {
try {
read = peer.getSocketChannel().read(readBuffer);
} catch (IOException e) {
key.cancel();
peer.disconnect("could not read...");
continue;
}
//check if this thread should exit!
if (interrupted()) {
return;
}
} else {
if (peer.readKey == null) {
System.out.println("ERROR 14276, encryption enabled, but I got no key?!?");
peer.disconnect("ERROR 14276");
continue;
}
read = peer.getSocketChannel().read(peer.readBufferCrypted);
//System.out.println("read bytes from socket " + read);
//check if this thread should exit!
if (interrupted()) {
return;
}
peer.readBufferCrypted.flip();
if (peer.readBuffer.remaining() <= 1024) {
System.out.println("############### readBuffer nearly full!! - " + peer.readBuffer.remaining());
}
int readCryptBytes = Math.min(peer.readBufferCrypted.remaining(), peer.readBuffer.remaining());
byte[] buffer = new byte[readCryptBytes];
peer.readBufferCrypted.get(buffer);
peer.readBufferCrypted.compact();
byte[] decrypt = peer.readKey.decrypt(buffer);
if (peer.readBuffer != null) {
peer.readBuffer.put(decrypt);
} else {
peer.disconnect("readbuffer null");
}
//System.out.println("entschluesselte bytes: " + Utils.bytesToHexString(encrypt));
}
// System.out.println("gggggggggg" + peer.readBuffer.toString());
// peer.readBuffer.limit(read);
// System.out.println("adadadadad" + peer.readBuffer.toString());
if (read == -2) {
System.out.println("hgdjawhgdzawdtgzaud");
}
if (read > 0) {
Test.inBytes += read;
peer.receivedBytes += read;
}
if (read == 0) {
if (readBuffer.hasRemaining()) {
//System.out.println("dgqdgqzudg23c365nx367t34t53 " + peer.readBuffer + " " + key.isReadable() + " " + key.isValid());
System.out.println("dafuq!");
//closeConnection(peer, key);
peer.disconnect("dafuq 2332");
continue;
}
if (peer.readBuffer.capacity() * 2 > 1024 * 1024) {
//throw new RuntimeException("buffer to high exiting!!!!");
System.exit(-199);
}
System.out.println("readbuffer raised!!!");
ByteBuffer allocate = ByteBuffer.allocate(peer.readBuffer.capacity() * 2);
allocate.put(peer.readBuffer.array());
allocate.position(peer.readBuffer.position());
// allocate.limit(peer.readBuffer.limit());
//System.out.println("buffer voll?? " + peer.readBuffer.toString());
peer.readBuffer = allocate;
// System.out.println("readBuffer full, generated new one with 2x larger size....");
} else if (read == -1) {
Log.put("closing connection " + peer.ip + ":" + peer.port + ": not readable! " + readBuffer, 200);
peer.disconnect(" read == -1 ");
Test.triggerOutboundthread();
key.cancel();
} else {
peer.lastActionOnConnection = System.currentTimeMillis();
//System.out.println("setting lastActionOn: " + peer.nonce);
// System.out.println("read bytes: " + read);
// System.out.println("a: " + read + " ");
// System.out.println(new String(.array(), 0, read));
//peer.getSocketChannel().write(allocate);
int pos = peer.readBuffer.position();
int lim = peer.readBuffer.limit();
int parsedBytes = 0;
peer.readBuffer.flip(); //switch buffer for reading
// System.out.println("incoming string: " + new String(peer.readBuffer.array(), peer.readBuffer.arrayOffset(), peer.readBuffer.limit()));
if (!peer.firstCommandsProceeded) {
if (peer.readBuffer.limit() > 14) { //start needs to be 15 bytes!
String magic = readString(peer.readBuffer, 4);
int version = (int) peer.readBuffer.get();
long nonce = readBuffer.getLong();
// byte[] nonce = new byte[10];
// peer.readBuffer.get(nonce);
int port = readUnsignedShort(readBuffer);
Log.put("Verbindungsaufbau (" + peer.ip + "): " + magic + " " + version + " " + nonce + " " + port, 10);
if (magic != null && magic.equals(Test.MAGIC) && version == Test.VERSION) {
//System.out.println("ready! " + magic);
peer.port = port;
peer.nonce = nonce;
if (nonce == Test.NONCE) {
Log.put("found myself!" + peer.ip + ":" + peer.port, 200);
Test.removeByIpAndPortPeer(peer);
peer.disconnect(" found myself");
continue;
}
//addPeer(new Peer(socket.getInetAddress().getHostAddress(), port));
// Peer newPeer = new Peer(peer.ip, port);
// newPeer.nonce = nonce;
boolean found = false;
// boolean closeNew = false;
Test.peerListLock.lock();
for (Peer pfromList : Test.getClonedPeerList()) {
if (pfromList.equals(peer)) {
continue;
}
if (peer.equalsNonce(pfromList)) {
found = true;
// System.out.println("nonce1: " + peer.nonce + " nonce2: " + pfromList.nonce);
if (pfromList.isConnected() || pfromList.isConnecting) {
Log.put("Peer already in peerlist... closing old connection...", 22);
pfromList.disconnect(" closing old con");
// System.out.println("Peer is already connected, closing new connection");
// peer.disconnect();
// closeNew = true;
// break;
}
//
// pfromList.setSocketChannel(peer.getSocketChannel());
// pfromList.ip = peer.ip;
// pfromList.port = port;
// pfromList.readBuffer = readBuffer;
// pfromList.writeBuffer = writeBuffer;
// pfromList.setSelectionKey(peer.getSelectionKey());
// key.attach(pfromList);
// //Test.peerList.remove(peer);//remove new generated peer
// peer = pfromList;
peer.migratePeer(pfromList);
//ToDo: block
Test.removePeer(pfromList);
Test.findPeerNonce(peer);
// System.out.println("dbwdwgzdw " + peer.isConnected());
//
// System.out.println("Migrated this connection to existend peer object...");
// System.out.println("since: " + pfromList.lastAllMsgsQuerried);
break;
}
}
if (!found) {
// System.out.println("Peer not found in list, adding new peer...");
//Test.peerList.add(peer);
Test.findPeerNonce(peer);
// System.out.println("IP: " + peer.ip + " nonce: " + peer.nonce);
}
// if (!closeNew) {
peer.port = port;
peer.connectedSince = System.currentTimeMillis();
peer.connectAble = 1;
peer.lastActionOnConnection = System.currentTimeMillis();
peer.firstCommandsProceeded = true;
// }
Test.peerListLock.unlock();
// if (Settings.lightClient) {
//// if (!found) { //new peer
// String out = ADDFILTERADDRESS + ":";
// for (Channel c : Test.getChannels()) {
// out += c.stringIdentity();
// out += ",";
// }
// out = out.substring(0, out.length() - 1);
// writeString(out);
//// }
// }
// //Peer nicley connected!
// writeString("getMsgs:" + peer.lastAllMsgsQuerried);
// if (!closeNew) {
//peer.retries = 0;
peer.writeBufferLock.lock();
//first ping...
peer.lastPinged = System.currentTimeMillis();
writeBuffer.put((byte) 100); //ping
//init auth
boolean foundAuthKey = false;
for (PeerTrustData pt : Test.peerTrusts) {
if (pt.nonce == peer.nonce) {
foundAuthKey = true;
// System.out.println("authkey found for nonce: " + peer.nonce);
Random r = new SecureRandom();
byte[] toEncrypt = new byte[32];
r.nextBytes(toEncrypt);
writeBuffer.put((byte) 52);
writeBuffer.put(toEncrypt);
peer.toEncodeForAuthFromMe = toEncrypt;
//peer.peerTrustData = pt;
// System.out.println("request authentication...");
//break;
}
}
if (!foundAuthKey) {
sendNewAuthKey(peer);
}
//auth end
peer.writeBufferLock.unlock();
peer.setWriteBufferFilled();
// }
} else {
peer.port = port;
System.out.println("WRONG magic and or protocoll - VERSION, deleting peer.... " + peer.ip + " " + peer.port);
Test.removeByIpAndPortPeer(peer);
peer.disconnect("WRONG magic and or protocoll");
}
parsedBytes = 15;
}
} else {
int localParsedBytes = 0;
while (peer.isConnected()) {
byte command = peer.readBuffer.get();
//System.out.println(peer.ip + "Command: " + command);
try {
localParsedBytes = parseCommands(command, peer, parsedBytes, writeBuffer, readBuffer);
} catch (Throwable thb) {
System.out.println("/////////////////// catched");
thb.printStackTrace();
}
//System.out.println(peer.ip + "parsed bytes: " + localParsedBytes);
if (peer.isCryptedConnection()) {
peer.parsedCryptedBytes += localParsedBytes;
}
if (localParsedBytes == -1) {
parsedBytes = 1; //somit ist nach dem naechste befehl alles auf 0 gesetzt! Buffer wurde entschluesselt... CMD 55!
}
parsedBytes += localParsedBytes;
if (localParsedBytes == 0 || !readBuffer.hasRemaining()) {
break;
}
if (peer.readBuffer == null) {
peer.disconnect("dafuq? 37456565");
System.out.println("dafuq? 37456565");
} else {
peer.readBuffer.position(parsedBytes);
}
//System.out.println("switched position of readbuffer: " + parsedBytes);
// System.out.println("parseBytes: " + parsedBytes + " " + peer.readBuffer);
// System.out.println("parseBytes: " + parsedBytes + " " + peer.readBuffer);
}
}
peer.setWriteBufferFilled(); //TODO: nachher besser machen?
//System.out.println("bytes in readbuffer: " + peer.readBuffer.remaining() + " parsedbytes: " + parsedBytes);
//int parseBytes = peer.readBuffer.limit() - peer.readBuffer.arrayOffset();
readBuffer.position(parsedBytes);
readBuffer.compact();
//peer.readBuffer.flip(); //switch buffer for writing
//readBuffer.limit(readBuffer.capacity());
//peer.readBuffer.limit(lim);
//peer.readBuffer.position(pos - parsedBytes);
}
} else if (key.isWritable()) {
//System.out.println("key is writeAble");
peer.writeBufferLock.lock();
if (peer.writeBuffer == null) {
try {
if (key.isValid()) {
key.interestOps(SelectionKey.OP_READ);
}
} catch (CancelledKeyException e) {
}
peer.writeBufferLock.unlock();
Log.put("writebuffer was null and writeable?", 0);
continue;
}
// int position = writeBuffer.position();
// int limit = writeBuffer.limit();
int writtenBytes = -1;
boolean remainingBytes = false;
peer.writeBuffer.flip();
if (peer.writeBufferCrypted == null) {
remainingBytes = peer.writeBuffer.hasRemaining();
} else {
peer.writeBufferCrypted.flip();
remainingBytes = (peer.writeBuffer.hasRemaining() || peer.writeBufferCrypted.hasRemaining());
peer.writeBufferCrypted.compact();
}
//System.out.println("remainingBytes: " + remainingBytes);
//switch buffer for reading
if (!remainingBytes) {
key.interestOps(SelectionKey.OP_READ);
//System.out.println("removed OP_WRITE");
} else {
//System.out.println("write from buffer...");
writtenBytes = peer.writeBytesToPeer(writeBuffer);
}
writeBuffer.compact();
// peer.writeBuffer.flip(); //switch buffer for writing
// writeBuffer.limit(writeBuffer.capacity());
// writeBuffer.limit(limit);
// writeBuffer.position(position - writtenBytes);
//System.out.println("wrote from buffer... " + writtenBytes + " ip: " + peer.ip);
Test.outBytes += writtenBytes;
peer.sendBytes += writtenBytes;
peer.writeBufferLock.unlock();
}
} catch (IOException e) {
key.cancel();
Peer peer = ((Peer) key.attachment());
System.out.println("error! " + peer.ip + ":" + peer.port);
e.printStackTrace();
peer.disconnect("IOException");
} catch (Throwable e) {
key.cancel();
Peer peer = ((Peer) key.attachment());
System.out.println("Catched fatal exception! " + peer.ip + ":" + peer.port);
e.printStackTrace();
//peer.disconnect(" IOException 4827f3fj");
Test.sendStacktrace("Fatal exception!", e);
peer.disconnect("Fatal exception");
}
}
}
System.out.println("ConnectionHandler thread died...");
}
public static void sendNewAuthKey(Peer peer) {
peer.peerTrustData = new PeerTrustData();
Random r = new SecureRandom();
byte[] myPart = new byte[16];
r.nextBytes(myPart);
if (peer.peerIsHigher()) {
System.arraycopy(myPart, 0, peer.peerTrustData.authKey, 0, 16);
} else {
System.arraycopy(myPart, 0, peer.peerTrustData.authKey, 16, 16);
}
peer.requestedNewAuth = true;
//request new
peer.writeBufferLock.lock();
peer.writeBuffer.put((byte) 51);
peer.writeBuffer.put(myPart);
peer.writeBufferLock.unlock();
//peer.authed = true;
Log.put("requested new authkey... " + peer.nonce, 150);
}
private int parseCommands(byte command, final Peer peer, int parsedBytes, final ByteBuffer writeBuffer, final ByteBuffer readBuffer) {
Log.put("Command byte: " + command + " ip:" + peer.ip, 150);
if (peer.getPeerTrustData() == null || !peer.authed) {
if (command == (byte) 1 || command == (byte) 2 || command == (byte) 10 || command == (byte) 51 || command == (byte) 52 || command == (byte) 53 || command == (byte) 55 || command == (byte) 100 || command == (byte) 101) {
// erlaubte befehle welche ohne verschluesselung ausgefuehrt werden duerfen
} else {
System.out.println("PEER wanted to send a command (" + command + ") which is only allowed after auth. : " + peer.ip);
peer.disconnect(" command but must be crypted");
return 0;
}
}
//System.out.println(peer.ip + " incoming command: " + command);
if (command == (byte) 1) {
Log.put("Command: get PeerList", 8);
ByteBuffer tempWriteBuffer = ByteBuffer.allocate(1024 * 10);
tempWriteBuffer.put((byte) 2);
ArrayList<Peer> clonedPeerList = Test.getClonedPeerList();
ArrayList<Peer> validPeers = new ArrayList<Peer>();
ArrayList<Peer> validPeersIPv6 = new ArrayList<Peer>();
for (Peer p1 : clonedPeerList) {
if (p1.equals(peer)) {
continue;
}
if (!p1.isConnected() || p1.writeBufferCrypted == null || !p1.authed) {
continue;
}
if (p1.connectAble == 1 && p1.ip.split("\\.").length == 4) {
if (validPeers.size() < 254) { //currently only 254 peers possible since the counter for it is just a byte. probably just send two seperated lists
validPeers.add(p1);
}
}
if (p1.connectAble == 1 && p1.ip.split("\\.").length != 4) {
validPeersIPv6.add(p1);
}
}
tempWriteBuffer.put((byte) validPeers.size());
tempWriteBuffer.put((byte) 0); // no ipv6 addresses yet
for (Peer p1 : validPeers) {
String[] split = p1.ip.split("\\.");
if (split.length == 4) { // muss nicht mehr gepruft werden, siehe valid peers...
for (String a : split) {
int asdd = Integer.parseInt(a);
//System.out.println("Int: " + (int) ((byte) asdd & 0xFF));
tempWriteBuffer.put((byte) asdd);
}
putUnsignedShot(tempWriteBuffer, p1.port);
}
}
for (Peer p1 : validPeersIPv6) {
if (p1.ip.length() > 250) {
System.out.println("konnte IPv6 nicht sharen, zu lang: " + p1.ip);
continue;
}
tempWriteBuffer.put((byte) 10);
tempWriteBuffer.put((byte) p1.ip.length());
tempWriteBuffer.put(p1.ip.getBytes());
putUnsignedShot(tempWriteBuffer, p1.port);
}
tempWriteBuffer.flip();
peer.writeBufferLock.lock();
writeBuffer.put(tempWriteBuffer);
peer.writeBufferLock.unlock();
return 1;
} else if (command == (byte) 2) {
Log.put("Command: peerList", 8);
if (2 > readBuffer.remaining()) {
return 0;
}
int ipv4addresses = (int) readBuffer.get() & 0xFF;
int ipv6addresses = (int) readBuffer.get() & 0xFF;
int needBytes = ipv4addresses * 6 + ipv6addresses * 18;
if (needBytes > readBuffer.remaining()) {
// System.out.println("Bytesremaining: " + readBuffer.remaining() + " ipv4 addresses: " + ipv4addresses);
return 0;
}
// System.out.println("parse " + ipv4addresses + " ipv4 addresses....");
for (int i = 0; i < ipv4addresses; i++) {
int ipblock1 = (int) readBuffer.get() & 0xFF;
int ipblock2 = (int) readBuffer.get() & 0xFF;
int ipblock3 = (int) readBuffer.get() & 0xFF;
int ipblock4 = (int) readBuffer.get() & 0xFF;
int port = readUnsignedShort(readBuffer);
String ip = ipblock1 + "." + ipblock2 + "." + ipblock3 + "." + ipblock4;
Peer peerToAdd = new Peer(ip, port);
boolean alreadyInList = false;
ArrayList<Peer> clonedPeerList = getClonedPeerList();
for (Peer tpeer : clonedPeerList) {
if (tpeer.equalsIpAndPort(peerToAdd)) {
alreadyInList = true;
}
}
//System.out.println("asdasdasd " + alreadyInList + " " + ip);
if (!alreadyInList) {
Test.messageStore.insertPeerConnectionInformation(ip, port, 0, System.currentTimeMillis());
}
}
return 1 + 2 + needBytes;
} else if (command == (byte) 3) {
Log.put("Command: sync!", 8);
if (2 > readBuffer.remaining()) {
return 0;
}
final long timestamp = readBuffer.getLong();
if (timestamp == -1) {
peer.syncMessagesSince = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7;
//full sync
syncAllMessagesSince(peer.syncMessagesSince, peer);
return 1 + 8;
}
int howMuchAddresses = readBuffer.get();
if (howMuchAddresses == 0) {
peer.syncMessagesSince = timestamp;
long myTime = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7;
if (Settings.SUPERNODE) {
myTime = 0;
}
syncAllMessagesSince(Math.max(timestamp, myTime), peer);
}
//obsolet??
if (howMuchAddresses * 33 > readBuffer.remaining()) {
return 0; //need more bytes in readBuffer...
}
//obsolet??
byte[] address = new byte[33];
for (int i = 0; i < howMuchAddresses; i++) {
readBuffer.get(address);
//ECKey eCKey = new ECKey(null, address);
ECKey eCKey = new ECKey(null, address, true);
System.out.println("Address to filter: " + eCKey);
}
return 1 + 8 + 1 + howMuchAddresses * 33;
} else if (command == (byte) 4) {
Log.put("Command: address to id", 8);
if (37 > readBuffer.remaining()) {
return 0;
}
byte[] address = new byte[33];
readBuffer.get(address);
//ECKey eCKey = new ECKey(null, address);
ECKey eCKey = new ECKey(null, address, true);
int id = readBuffer.getInt();
//System.out.println("address to id: " + Channel.byte2String(eCKey.getPubKey()) + " id: " + id);
//eCKey.database_id = Test.messageStore.getPubkeyId(eCKey);
// if (peer.keyToIdHis.get(id) == null) {
// System.out.println("Warning, index not found... closing connection...");
// peer.disconnect();
// return 1 + 37;
// }
//peer.keyToIdHis.put(id, eCKey);
peer.getKeyToIdHis().put(id, eCKey);
return 1 + 37;
} else if (command == (byte) 5) {
Log.put("Command: have message", 10);
if (21 > readBuffer.remaining()) {
return 0;
}
int pubkey_id_local = readBuffer.getInt();
byte public_type = readBuffer.get();
long timestamp = readBuffer.getLong();
int nonce = readBuffer.getInt();
int messageId = readBuffer.getInt();
//peer.peerTrustData.introducedMessages++;
ECKey id2KeyHis = peer.getId2KeyHis(pubkey_id_local);
//System.out.println("Key for message: " + Channel.byte2String(id2KeyHis.getPubKey()));
if (id2KeyHis == null) {
System.out.println("WARNING: key not found -.- " + pubkey_id_local + " " + peer.getKeyToIdHis().size() + " --- disconnect");
// for (Entry<Integer, ECKey> entry :peer.keyToIdHis.entrySet()) {
//
// System.out.println("");
//
// }
peer.disconnect("key not found 32323.");
return 1 + 21;
}
RawMsg rawMsg = new RawMsg(id2KeyHis, timestamp, nonce);
rawMsg.public_type = public_type;
//boolean contains = MessageHolder.contains(rawMsg);
//System.out.println("Peer got following msg: " + timestamp + " " + channelId + " " + nonce + " " + messageId);
//if (!contains) {
// System.out.println("found msg i want to have...");
boolean dontAddMessage = false;
//Check if I realy want this message, perhaps I removed the channel or the other side is spamming me.
// or i just wrote to a channel i'm not listening to, like the main channel!!!
if (Settings.lightClient) {
if (!peer.myInterestedChannelsCodedInHisIDs.contains(pubkey_id_local)) {
//int my_pubkeyId = Test.messageStore.getPubkeyId(id2KeyHis);
if (Test.channels.contains(new Channel(id2KeyHis, null))) {
peer.myInterestedChannelsCodedInHisIDs.add(pubkey_id_local);
Log.put("added !! " + pubkey_id_local + " node: " + peer.nonce, 100);
} else {
int pubkeyId = Test.messageStore.getPubkeyId(id2KeyHis);
peer.writeBufferLock.lock();
ECKey k = id2KeyHis;
if (!peer.peerTrustData.keyToIdMine.contains(pubkeyId)) {
peer.peerTrustData.keyToIdMine.add(pubkeyId);
//int indexOf = keyToIdMine.indexOf(k);
int indexOf = pubkeyId;
peer.writeBuffer.put((byte) 4);
peer.writeBuffer.put(k.getPubKey());
peer.writeBuffer.putInt(indexOf);
Log.put("key introduced", 0);
}
peer.writeBuffer.put((byte) 62);
peer.writeBuffer.putInt(pubkeyId);
peer.writeBufferLock.unlock();
dontAddMessage = true;
Log.put("channel was removed, sending to node.... " + pubkeyId + " node: " + peer.nonce, 0);
//There may be still messages to sync to other nodes, we have to remove them!!
//ToDo: replace this hack!
Test.messageStore.removeMessageToSend(peer.getPeerTrustData().internalId);
}
}
Log.put("contains!!! " + pubkey_id_local + " node: " + peer.nonce, 100);
}
if (!dontAddMessage) {
HashMap<PeerTrustData, Long> perKey = ratingData.get(id2KeyHis);
if (perKey == null) {
perKey = new HashMap<PeerTrustData, Long>();
ratingData.put(id2KeyHis, perKey);
}
//// Long time = perKey.get(peer.peerTrustData);
//// if (time != null && time != 0L) {
//// //there is already a time, we have to evaluate last round...
//// System.out.println("there is already a time, we have to evaluate last round...");
////
//// ArrayList<PeerTrustData> keySet = new ArrayList<PeerTrustData>(perKey.keySet());
////
//// final HashMap<PeerTrustData, Long> perKeyFinal = perKey;
//// Collections.sort(keySet, new Comparator<PeerTrustData>() {
////
//// @Override
//// public int compare(PeerTrustData t, PeerTrustData t1) {
//// return (int) (perKeyFinal.get(t) - perKeyFinal.get(t1));
//// }
//// });
////
//// int valueToAdd = 0;
////
//// for (PeerTrustData ptd : keySet) {
////
//// if (ptd == peer.peerTrustData) {
//// continue;
//// }
////
//// long diff = peer.peerTrustData.rating - ptd.rating;
//// double value1 = 10 / (1 + Math.pow(10, (float) diff / 8)) * 20;
////
//// int value = (int) Math.floor(value1);
////
//// if (value == 0) {
//// value = 1;
//// }
////
//// ptd.rating += -value;
//// valueToAdd += value;
////
//// System.out.println(perKey.get(ptd) + " - value: " + (-value) + " - " + ptd.rating + " - " + ptd.ips);
//// //reset round!
//// perKey.put(ptd, 0L);
//// }
////
//// peer.peerTrustData.rating += valueToAdd;
//// System.out.println(perKey.get(peer.peerTrustData) + " - Winner: " + (valueToAdd) + " - " + peer.peerTrustData.rating + " - " + peer.peerTrustData.ips);
////
//// }
////
//// perKey.put(peer.peerTrustData, System.currentTimeMillis());
peer.addPendingMessage(messageId, rawMsg);
//Test.messageStore.addMsgIntroducedToMe(peer.getPeerTrustData().internalId, messageId);
peer.getPeerTrustData().synchronizedMessages++;
Log.put("added pending msg... + " + peer.ip + " - " + messageId, 60);
// synchronized (writeBuffer) {
// writeBuffer.put((byte) 6);
// writeBuffer.putInt(messageId);
// }
//}
}
return 1 + 21;
} else if (command == (byte) 6) {
Log.put("Command: get message content " + peer.ip + ":" + peer.port, -2);
if (4 > readBuffer.remaining()) {
return 0;
}
final int id = readBuffer.getInt();
Runnable runnable = new Runnable() {
@Override
public void run() {
final String orgName = Thread.currentThread().getName();
if (!orgName.contains(" ")) {
Thread.currentThread().setName(orgName + " - send Message Thread");
}
RawMsg rawMsg = null;
rawMsg = MessageHolder.getRawMsg(id);
Log.put("message to fetch by id: " + id, -2);
if (rawMsg == null) {
System.out.println("HM diese Nachricht habe ich nicht, id: " + id + " ip: " + peer.getIp());
return;
}
//ToDo: msg might have been deleted due to false signature...
if (rawMsg.getContent() == null || rawMsg.getContent().length > 1024 * 201) {
Main.sendBroadCastMsg("ohoh, rawMsg.getContent() is null or too long...");
return;
}
int cnt = 0;
peer.writeBufferLock.lock();
while (peer.writeBuffer != null && peer.writeBuffer.remaining() < rawMsg.getContent().length + 1 + 4 + 72) {
if (!peer.isConnected()) {
peer.writeBufferLock.unlock();
return;
}
cnt++;
try {
peer.writeBufferLock.unlock();
sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Buffer full, cnt: " + cnt + " contentlen: " + rawMsg.getContent().length + " remaining: " + ((peer.writeBuffer != null) ? peer.writeBuffer.remaining() : "null"));
if (cnt == 100) {
Main.sendBroadCastMsg("CODE 2kcvh5: buffer to small..." + cnt);
peer.writeBufferLock.unlock();
return;
}
peer.writeBufferLock.lock();
}
if (peer.writeBuffer == null) {
System.out.println("writebuffer was null while, wanted to write msg to node");
return;
}
writeBuffer.put((byte) 7);
writeBuffer.putInt(id);
if (rawMsg.getSignature().length != 72) {
throw new RuntimeException("hreuhrwuirhew signature got wrong length!!!");
}
writeBuffer.put(rawMsg.getSignature());
writeBuffer.putInt(rawMsg.getContent().length);
// if (writeBuffer.remaining() < rawMsg.getContent().length) {
// ByteBuffer allocate = ByteBuffer.allocate(writeBuffer.capacity() + rawMsg.getContent().length + 30);
// allocate.put(writeBuffer.array());
// //allocate.position(writeBuffer.position());
// peer.writeBuffer = allocate;
// }
//System.out.println("SIZE:" + writeBuffer.remaining() + " " + rawMsg.getContent().length);
//System.out.println("bytes: " + rawMsg.getContent().length);
//NullPointer thrown in HeapByteBuffer, dont know why, so hack!
try {
//todo: catch via another way?
peer.writeBuffer.put(rawMsg.getContent());
} catch (Throwable e) {
Main.sendBroadCastMsg("prevented exception 73632.");
peer.disconnect("prevented exception 73632");
}
peer.writeBufferLock.unlock();
peer.setWriteBufferFilled();
Log.put("wrote msg to peer " + peer.ip + " with byte length: " + rawMsg.getContent().length + " msgid: " + rawMsg.database_Id, -2);
}
};
threadPool2.execute(runnable);
//new Thread(runnable).start();
return 1 + 4;
} else if (command == (byte) 7) {
//message content
if (4 + RawMsg.SIGNATURE_LENGRTH + 4 > readBuffer.remaining()) {
return 0;
}
final int msgId = readBuffer.getInt();
byte[] signature = new byte[RawMsg.SIGNATURE_LENGRTH];
readBuffer.get(signature);
//System.out.println("SIGNATURE : " + Utils.bytesToHexString(signature));
int contentLength = readBuffer.getInt();
// System.out.println("###### content len: " + contentLength);
if (contentLength > readBuffer.remaining()) {
Log.put("not enough bytes yet... missing: " + (contentLength - readBuffer.remaining()) + " got: " + readBuffer.remaining() + " needed: " + contentLength, 20);
return 0;
}
// Log.put("Command: msg content incoming...", 8);
byte[] content = new byte[contentLength];
readBuffer.get(content);
RawMsg get = peer.getPendingMessages().get(msgId);
//RawMsg get = Test.messageStore.getMessageById(msgId);
if (get == null) {
get = peer.getPendingMessagesTimedOut().get(msgId);
if (get == null) {
System.out.println("WARNING: got message content for a message I cant find... " + msgId + " " + peer.getPendingMessages().size() + " ip: " + peer.ip);
return 1 + 4 + RawMsg.SIGNATURE_LENGRTH + 4 + contentLength;
}
System.out.println("WARNING: get message content for a timed out message... trying to add content to database...." + msgId + " " + peer.getPendingMessages().size() + " ip: " + peer.ip);
}
get.signature = signature;
get.content = content;
MessageDownloader.publicMsgsLoadedLock.lock();
MessageDownloader.publicMsgsLoaded++;
MessageDownloader.publicMsgsLoadedLock.unlock();
final RawMsg getFinal = get;
Log.put("execute new msg thread", 70);
Runnable runnable = new Runnable() {
@Override
public void run() {
final String orgName = Thread.currentThread().getName();
if (!orgName.contains(" ")) {
Thread.currentThread().setName(orgName + " - addMessage + pr. broadcast");
}
RawMsg addMessage = MessageHolder.addMessage(getFinal);
peer.requestedMsgs--;
MessageDownloader.removeRequestedMessage(getFinal);
//System.out.println("DWGDYWGDYW " + addMessage.key.database_id);
// synchronized (peer.getPendingMessages()) {
// peer.getPendingMessages().remove(msgId);
// }
Log.put("msg: " + getFinal.timestamp + " " + getFinal.nonce, 100);
if (addMessage.getChannel() == null) {
//isPublic...
MessageDownloader.publicMsgsLoaded++;
}
// System.out.println("KEY: " + Channel.byte2String(addMessage.key.getPubKey()));
// System.out.println("timestamp: " + addMessage.timestamp);
// System.out.println("CONTENT hash: " + Sha256Hash.create(addMessage.content));
// System.out.println("signature hash: " + Sha256Hash.create(addMessage.signature));
synchronized (peer.getLoadedMsgs()) {
peer.addLoadedMsg(addMessage.database_Id);
}
if (addMessage.key.database_id == -1) {
addMessage = MessageHolder.addMessage(addMessage);
System.out.println("woooot " + Utils.bytesToHexString(getFinal.key.getPubKey()) + " " + getFinal.timestamp);
}
if (addMessage.key.database_id == -1) {
System.out.println("#####CODE: 19564 - NICHT GUT!!!! - try again to get PUBKEY ID");
RawMsg again = MessageHolder.addMessage(addMessage);
System.out.println("#####Key id is now: " + again.key.database_id);
System.out.println("#####Message not broadcasted...");
return;
}
if (!Settings.BROADCAST_MSGS_AFTER_VERIFICATION) {
Test.broadcastMsg(addMessage);
}
MessageDownloader.trigger();
MessageVerifierHsqlDb.trigger();
if (peer.maxSimultaneousRequests <= MessageDownloader.MAX_REQUEST_PER_PEER) {
peer.maxSimultaneousRequests++;
Log.put("increased max req to: " + peer.maxSimultaneousRequests, -1);
}
}
};
threadPool.execute(runnable);
//runnable.run();
// new Thread() {
//
// @Override
// public void run() {
// try {
// sleep(10000);
// } catch (InterruptedException ex) {
// Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
// }
// peer.requestedMsgs--;
// MessageDownloader.trigger();
// }
// }.start();
Log.put(
"parsed bytes: " + (1 + 4 + RawMsg.SIGNATURE_LENGRTH + 4 + contentLength) + " remainig: " + readBuffer.remaining(), 200);
return 1 + 4 + RawMsg.SIGNATURE_LENGRTH + 4 + contentLength;
} else if (command == (byte) 8) {
Log.put("Command: control data request...", 8);
PeerTrustData peerTrustData = peer.getPeerTrustData();
//ToDo: remove 0.s
peer.writeBufferLock.lock();
writeBuffer.put((byte) 9);
writeBuffer.putInt(0);
writeBuffer.putInt(peerTrustData.keyToIdHis.size());
writeBuffer.putInt(peerTrustData.keyToIdMine.size());
writeBuffer.putInt(0);
ArrayList<Integer> keySet = new ArrayList<Integer>(peerTrustData.keyToIdHis.keySet());
Collections.sort(keySet);
// String toHashkeyToIdHis = "";
// for (Entry<Integer, ECKey> entry : peerTrustData.keyToIdHis.entrySet()) {
// int key = entry.getKey();
// toHashkeyToIdHis += "" + key;
// }
String toHashkeyToIdHis = "";
for (Integer key : keySet) {
toHashkeyToIdHis += "" + key;
}
Collections.sort(peerTrustData.keyToIdMine);
String toHashkeyToIdMine = "";
for (int key : peerTrustData.keyToIdMine) {
toHashkeyToIdMine += "" + key;
}
try {
writeBuffer.putInt(Sha256Hash.create(toHashkeyToIdMine.getBytes("UTF-8")).hashCode());
writeBuffer.putInt(Sha256Hash.create(toHashkeyToIdHis.getBytes("UTF-8")).hashCode());
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
peer.writeBufferLock.unlock();
return 1;
} else if (command == (byte) 9) {
if (4 + 4 + 4 + 4 + 4 + 4 > readBuffer.remaining()) {
return 0;
}
PeerTrustData peerTrustData = peer.getPeerTrustData();
int introducedMessages = readBuffer.getInt();
int keyToIdHis = readBuffer.getInt();
int keyToIdMine = readBuffer.getInt();
int sendMessages = readBuffer.getInt();
int hashkeyToIdMine = readBuffer.getInt();
int hashkeyToIdHis = readBuffer.getInt();
//mine = his
//System.out.println("keyToIdHis: " + peerTrustData.keyToIdHis.size() + " - " + keyToIdMine);
//System.out.println("keyToIdMine: " + peerTrustData.keyToIdMine.size() + " - " + keyToIdHis);
Set<Integer> keySet = peerTrustData.keyToIdHis.keySet();
ArrayList<Integer> arrayList = new ArrayList<Integer>(keySet);
// Comparator<Integer> comparator = new Comparator<Integer>() {
// public int compare(Integer o1, Integer o2) {
// return 0;
// }
// };
Collections.sort(arrayList);
String toHashkeyToIdHis = "";
for (int key : arrayList) {
toHashkeyToIdHis += "" + key;
}
Collections.sort(peerTrustData.keyToIdMine);
String toHashkeyToIdMine = "";
for (int key : peerTrustData.keyToIdMine) {
toHashkeyToIdMine += "" + key;
}
try {
int myHashkeyToIdMine = Sha256Hash.create(toHashkeyToIdMine.getBytes("UTF-8")).hashCode();
int myHashkeyToIdHis = Sha256Hash.create(toHashkeyToIdHis.getBytes("UTF-8")).hashCode();
Log.put("Hash keyToIdMine: " + myHashkeyToIdHis + " - " + hashkeyToIdMine, 30);
if (peerTrustData.keyToIdHis.size() != keyToIdMine || myHashkeyToIdHis != hashkeyToIdMine) {
System.out.println("keyToIdHis wrong, clearing....");
System.out.println("list: " + toHashkeyToIdHis);
peerTrustData.keyToIdHis.clear();
}
Log.put("Hash keyToIdMine: " + myHashkeyToIdMine + " - " + hashkeyToIdHis, 30);
if (peerTrustData.keyToIdMine.size() != keyToIdHis || myHashkeyToIdMine != hashkeyToIdHis) {
System.out.println("keyToIdMine wrong, clearing....");
System.out.println("list: " + toHashkeyToIdMine);
peerTrustData.keyToIdMine.clear();
}
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
// boolean trimedSendMsgs = false;
// while (peerTrustData.sendMessages.size() > introducedMessages) {
// peerTrustData.sendMessages.remove(peerTrustData.sendMessages.size() - 1);
// trimedSendMsgs = true;
// }
// if (trimedSendMsgs) {
// System.out.println("trimed sendMessages...");
// }
//
// boolean trimedIntroducedMessages = false;
// while (peerTrustData.introducedMessages.size() > sendMessages) {
// peerTrustData.introducedMessages.remove(peerTrustData.introducedMessages.size() - 1);
// trimedIntroducedMessages = true;
// }
// if (trimedIntroducedMessages) {
// System.out.println("trimed introducedMessages...");
// }
// for (Channel channel : Test.getChannels()) {
// byte[] pubKey = channel.getKey().getPubKey();
//
// //System.out.println("Channel key length: " + pubKey.length);
//// writeBuffer.put((byte) 60);
//// writeBuffer.put();
// }
if (Settings.lightClient) {
//remove -1 for migration from super node to light node.
peer.writeBuffer.put((byte) 62);
peer.writeBuffer.putInt(-1);
for (Channel channel : Test.channels) {
if (!peer.getPeerTrustData().sendChannelsToFilter.contains(peer)) {
peer.sendChannelToFilter(channel.key);
}
}
//TODO: code remove routine....
} else {
peer.writeBufferLock.lock();
//hack for version compability - remove later!!!
//ToDo: remove later
if (!peerTrustData.keyToIdMine.contains(-1)) {
peerTrustData.keyToIdMine.add(-1);
writeBuffer.put((byte) 4);
writeBuffer.put(new byte[33]);
writeBuffer.putInt(-1);
//System.out.println("Msg index: " + indexOf);
}
peer.writeBuffer.put((byte) 60);
peer.writeBuffer.putInt(-1);
peer.writeBufferLock.unlock();
}
peer.writeBufferLock.lock();
//init sync
writeBuffer.put((byte) 3);
//sync last two days
//writeBuffer.putLong(-1);// full sync!
//writeBuffer.putLong(0);
//writeBuffer.putLong(Math.max(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 2, Settings.till));
//writeBuffer.putLong(Math.max(System.currentTimeMillis() - 1000 * 60, Settings.till));
//writeBuffer.putLong(System.currentTimeMillis() - 1000 * 60 * 60);
long myTime = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7;
if (Settings.SUPERNODE) {
myTime = 0;
}
writeBuffer.putLong(myTime);
writeBuffer.put((byte) 0);
//get PeerList
writeBuffer.put((byte) 1);
// peer.setWriteBufferFilled();
peer.writeBufferLock.unlock();
return 1 + 4 + 4 + 4 + 4 + 4 + 4;
} else if (command == (byte) 10) {
if (1 + +1 + 2 > readBuffer.remaining()) {
return 0;
}
byte get = readBuffer.get();
if (get < 1) {
System.out.println("omg, wrong IP address length....");
peer.disconnect("ip address len < 0");
return 0;
}
if (1 + 1 + ((int) get) + 2 > readBuffer.remaining()) {
return 0;
}
byte[] ipBytes = new byte[get];
readBuffer.get(ipBytes);
String ip = new String(ipBytes);
int port = readUnsignedShort(readBuffer);
Peer newPeer = new Peer(ip, port);
//System.out.println("Peerexchange: new peer " + ip + ":" + port);
Test.findPeer(newPeer);
return 1 + 1 + get + 2;
} else if (command == (byte) 51) {
if (1 + 16 > readBuffer.remaining()) {
return 0;
}
byte[] otherAuthKeyBytes = new byte[16];
readBuffer.get(otherAuthKeyBytes);
if (!peer.requestedNewAuth) {
//dafuq, thought I had an authkey for node. Generating new AuthKey
System.out.println("dafuq, thought I had an authkey for node. Generating new AuthKey: " + peer.nonce);
//peer.peerTrustData = new PeerTrustData();
sendNewAuthKey(peer);
}
if (peer.peerIsHigher()) {
System.arraycopy(otherAuthKeyBytes, 0, peer.peerTrustData.authKey, 16, 16);
} else {
System.arraycopy(otherAuthKeyBytes, 0, peer.peerTrustData.authKey, 0, 16);
}
peer.peerTrustData.nonce = peer.nonce;
Test.peerTrusts.add(peer.peerTrustData);
peer.peerTrustData.initInternalId();
saveTrustData();
System.out.println("added key from other side... " + peer.nonce);
System.out.println("requesting auth ...: " + peer.nonce);
Random r = new SecureRandom();
byte[] toEncrypt = new byte[32];
r.nextBytes(toEncrypt);
peer.writeBufferLock.lock();
writeBuffer.put((byte) 52);
writeBuffer.put(toEncrypt);
peer.writeBufferLock.unlock();
peer.toEncodeForAuthFromMe = toEncrypt;
//peer.peerTrustData = pt;
// System.out.println("request authentication...");
return 1 + 16;
} else if (command == (byte) 52) {
if (32 > readBuffer.remaining()) {
return 0;
}
byte[] toEnc = new byte[32];
readBuffer.get(toEnc);
boolean send = false;
for (PeerTrustData pt : Test.peerTrusts) {
if (pt.nonce != peer.nonce) {
continue;
}
byte[] encode = AESCrypt.encode(pt.authKey, toEnc);
peer.toEncodeForAuthFromHim = toEnc;
peer.writeBufferLock.lock();
writeBuffer.put((byte) 53);
writeBuffer.put(encode);
peer.writeBufferLock.unlock();
send = true;
}
peer.setWriteBufferFilled();
if (!send) {
System.out.println("ERROR 77877");
}
//System.out.println("encoded data with authKey... " + Utils.bytesToHexString(toEnc) + " len: " + toEnc.length);
//System.out.println("encoded data with authKey... " + Utils.bytesToHexString(encode) + " len: " + encode.length);
return 1 + 32;
} else if (command == (byte) 53) {
if (48 > readBuffer.remaining()) {
System.out.println("zu wenig bytes.... " + readBuffer.remaining());
return 0;
}
byte[] thereEnc = new byte[48];
readBuffer.get(thereEnc);
if (peer.toEncodeForAuthFromHim == null || peer.toEncodeForAuthFromMe == null) {
System.out.println("FATAL ERROR: 48727 - auth failed");
return 1 + 48;
}
boolean found = false;
for (PeerTrustData pt : Test.peerTrusts) {
if (pt.nonce != peer.nonce) {
continue;
}
found = true;
byte[] myEnc = AESCrypt.encode(pt.authKey, peer.toEncodeForAuthFromMe);
if (Arrays.equals(thereEnc, myEnc)) {
peer.peerTrustData = pt;
//System.out.println("Auth successfull with nonce: " + peer.nonce);
peer.authed = true;
//Schluessel ist peer.peer.peerTrustData.authKey + thereEnc + myEnc, falls die Verbindung von aussem kommt.
//ansonsten vertausche thereEnc mit myEnc.
byte[] rc4CrpytKeySeedWrite = new byte[32 + 32 + 32];
byte[] rc4CrpytKeySeedRead = new byte[32 + 32 + 32];
System.arraycopy(peer.peerTrustData.authKey, 0, rc4CrpytKeySeedWrite, 0, 32);
System.arraycopy(peer.peerTrustData.authKey, 0, rc4CrpytKeySeedRead, 0, 32);
if (peer.peerIsHigher()) {
//System.out.println("Im higher");
System.arraycopy(peer.toEncodeForAuthFromMe, 0, rc4CrpytKeySeedWrite, 32, 32);
System.arraycopy(peer.toEncodeForAuthFromHim, 0, rc4CrpytKeySeedWrite, 64, 32);
System.arraycopy(peer.toEncodeForAuthFromHim, 0, rc4CrpytKeySeedRead, 32, 32);
System.arraycopy(peer.toEncodeForAuthFromMe, 0, rc4CrpytKeySeedRead, 64, 32);
} else {
//System.out.println("Im lower");
System.arraycopy(peer.toEncodeForAuthFromMe, 0, rc4CrpytKeySeedRead, 32, 32);
System.arraycopy(peer.toEncodeForAuthFromHim, 0, rc4CrpytKeySeedRead, 64, 32);
System.arraycopy(peer.toEncodeForAuthFromHim, 0, rc4CrpytKeySeedWrite, 32, 32);
System.arraycopy(peer.toEncodeForAuthFromMe, 0, rc4CrpytKeySeedWrite, 64, 32);
}
// System.out.println("My NONCE: " + Test.NONCE);
// System.out.println("There NONCE: " + peer.nonce);
// System.out.println("KABUM, initialisiere Verschluesselung, key fuer ARC4 " + Utils.bytesToHexString(rc4CrpytKeySeed));
//
// System.out.println("my: " + Utils.bytesToHexString(myEnc));
// System.out.println("te: " + Utils.bytesToHexString(thereEnc));
byte[] rc4CryptKeyFalseWrite = Sha256Hash.create(rc4CrpytKeySeedWrite).getBytes();
byte[] rc4CryptKeyFalseRead = Sha256Hash.create(rc4CrpytKeySeedRead).getBytes();
// System.out.println("Hashed key is: " + Utils.bytesToHexString(rc4CryptKey));
//System.out.println("KABUM, initialisiere Verschluesselung, key fuer ARC4 " + Utils.bytesToHexString(rc4CryptKeyFalseWrite) + " -- " + Utils.bytesToHexString(rc4CryptKeyFalseRead));
//System.out.println("ARC4 active. IP: " + peer.ip);
//Beide bruachen einen eigenen rc4 verschluesseler da sich der Key aendert mit jedem byte welches verschluesselt wird...
//System.out.println("Key length: " + rc4CryptKeyFalse.length);
//Key fuer RC4 darf nur max 31 bytes haben, loesche letztes byte...
byte[] rc4CryptKeyWrite = new byte[31];
byte[] rc4CryptKeyRead = new byte[31];
System.arraycopy(rc4CryptKeyFalseWrite, 0, rc4CryptKeyWrite, 0, 31);
System.arraycopy(rc4CryptKeyFalseRead, 0, rc4CryptKeyRead, 0, 31);
if (peer.peerIsHigher()) {
peer.writeKey = new RC4(rc4CryptKeyWrite);
peer.readKey = new RC4(rc4CryptKeyRead);
} else {
peer.writeKey = new RC4(rc4CryptKeyRead);
peer.readKey = new RC4(rc4CryptKeyWrite);
}
peer.peerTrustData.lastSeen = System.currentTimeMillis();
Log.put("PEER is now trusted...", 300);
if (peer.peerTrustData.ips.contains(peer.ip)) {
Log.put("IP schon in den trusted Data...", 200);
} else {
if (peer.peerTrustData.ips.size() > 10) {
peer.peerTrustData.ips.clear();
}
peer.peerTrustData.ips.add(peer.ip);
peer.peerTrustData.port = peer.port;
Log.put("IP added and port set!", 300);
}
peer.removeRequestedMsgs();
pt.pendingMessages = new HashMap<Integer, RawMsg>();
pt.pendingMessagesTimedOut = new HashMap<Integer, RawMsg>();
pt.pendingMessagesPublic = new HashMap<Integer, RawMsg>();
peer.writeBufferLock.lock();
//ab nun werden alle bytes verschluesselt, dies wird mit dem folgenden Befehl gestarted
writeBuffer.put((byte) 55);
//schicke dieses byte noch unverschluesselt...
//peer.setWriteBufferFilled();
peer.writeBufferLock.lock();
int writtenBytes = 0;
peer.writeBuffer.flip(); //switch buffer for reading
try {
writtenBytes = peer.writeBytesToPeer(peer.writeBuffer);
} catch (IOException ex) {
ex.printStackTrace();
}
Test.outBytes += writtenBytes;
peer.sendBytes += writtenBytes;
peer.writeBuffer.compact();
if (peer.writeBuffer.position() != 0) {
System.out.println("ACHTUNG konnte nun verschluessel byte nicht direkt schicken...");
}
peer.writeBufferLock.unlock();
// try {
// sleep(3000);
// } catch (InterruptedException ex) {
// Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
// }
//TODO make better
//peer.writeBufferCrypted = ByteBuffer.allocate(peer.writeBuffer.capacity());
//peer.readBufferCrypted = ByteBuffer.allocate(peer.readBuffer.capacity());
try {
peer.writeBufferCrypted = ByteBuffer.allocate(1024 * 1024);
} catch (Throwable e) {
e.printStackTrace();
System.out.println("Speicher konnte nicht reserviert werden2. Disconnect peer...");
peer.disconnect("speicher voll 34642");
return 0;
}
//FULL CONNECTED TO NODE!
//NUN darf die Verbindung genutzt werden zum syncen usw...
writeBuffer.put((byte) 8);
peer.writeBufferLock.unlock();
//peer.getPeerTrustData().removeNotSuccesfulSendMessages();
peer.retries = 0;
//peer.setWriteBufferFilled();
//System.out.println("send byte 8 to node");
break;
} else {
//System.out.println("WARNING: auth failed with nonce: " + peer.nonce + " key: " + Utils.bytesToHexString(pt.authKey));
//System.out.println("DATA: " + Utils.bytesToHexString(myEnc));
//System.out.println("DATA: " + Utils.bytesToHexString(thereEnc));
}
}
if (!found) {
System.out.println("erm, nicht gefunden?!?");
}
return 1 + 48;
} else if (command == (byte) 55) {
if (peer.readKey == null) {
System.out.println("ERROR 14275, peer wants to crypt connection, but i got no key?!?");
peer.disconnect("ERROR 14275");
return 0;
}
try {
peer.readBufferCrypted = ByteBuffer.allocate(READ_BUFFER_SIZE);
} catch (Throwable e) {
System.out.println("Speicher konnte nicht reserviert werden3. Disconnect peer...");
peer.disconnect("Speicher konnte nicht reserviert werden3.");
}
//System.out.println("ab nun wird der lese strom entschluesselt...");
//readBuffer.get();//index einen weiter schieben, (byte) 55 wurde schon verarbeitet oder auch nicht?
//Verschluessel die schon gelesenen bytes...
if (readBuffer.hasRemaining()) {
//System.out.println("OH OH das wird schief gehen, remaining bytes: " + readBuffer.remaining());
synchronized (peer.readBuffer) {
byte[] buffer = new byte[peer.readBuffer.remaining()];
peer.readBuffer.get(buffer);
peer.readBuffer.compact();
byte[] decrypt = peer.readKey.decrypt(buffer);
// peer.readBuffer.clear();
peer.readBuffer.put(decrypt);
peer.readBuffer.flip();
// peer.readBufferCrypted.put(buffer);
//System.out.println("ENCRYPTED: " + Utils.bytesToHexString(encrypt));
return -1; //readbuffer darf nicht mehr verschoben werden!
}
}
return 1;//ja das muss so!!
} else if (command == (byte) 60) {
//addFilterMessage
if (4 > readBuffer.remaining()) {
System.out.println("zu wenig bytes.... " + readBuffer.remaining());
return 0;
}
final int hisKeyId = readBuffer.getInt();
//ECKey get = peer.getKeyToIdHis().get(hisKeyId);
if (hisKeyId == -1) {
//all channels...
Test.messageStore.addFilterChannel(peer.getPeerTrustData().internalId, -1);
Log.put("added all channels to get messages from: " + peer.ip, 20);
} else {
ECKey id2KeyHis = peer.getId2KeyHis(hisKeyId);
if (id2KeyHis == null) {
//id2keys wrong!
peer.disconnect("id2KeyHis null");
} else {
int pubkeyIdMine = Test.messageStore.getPubkeyId(id2KeyHis);
//System.out.println("FILTERMSG ID: " + pubkeyIdMine);
Test.messageStore.addFilterChannel(peer.getPeerTrustData().internalId, pubkeyIdMine);
}
}
return 1 + 4;
} else if (command == (byte) 61) {
//set Client Type
System.out.println("command not supported, yet");
return 1 + 4;
} else if (command == (byte) 62) {
//remove channel - delFilterMessage
if (4 > readBuffer.remaining()) {
System.out.println("zu wenig bytes.... " + readBuffer.remaining());
return 0;
}
final int hisKeyId = readBuffer.getInt();
//ECKey get = peer.getKeyToIdHis().get(hisKeyId);
if (hisKeyId == -1) {
Test.messageStore.delFilterChannel(peer.getPeerTrustData().internalId, -1);
} else {
ECKey id2KeyHis = peer.getId2KeyHis(hisKeyId);
if (id2KeyHis == null) {
//id2keys wrong!
peer.disconnect("id2KeyHis null");
} else {
int pubkeyIdMine = Test.messageStore.getPubkeyId(id2KeyHis);
Test.messageStore.delFilterChannel(peer.getPeerTrustData().internalId, pubkeyIdMine);
}
}
return 1 + 4;
} else if (command == (byte) 70) {
if (8 > readBuffer.remaining()) {
System.out.println("zu wenig bytes.... " + readBuffer.remaining());
return 0;
}
long timestamp = readBuffer.getLong();
System.out.println("syncing back in time...");
syncMessagesBack(timestamp, peer, 100);
return 1 + 8;
} else if (command == (byte) 71) {
if (8 > readBuffer.remaining()) {
System.out.println("zu wenig bytes.... " + readBuffer.remaining());
return 0;
}
long timestamp = readBuffer.getLong();
peer.getPeerTrustData().backSyncedTill = timestamp;
System.out.println("setted back sync time to: " + timestamp);
return 1 + 8;
} else if (command == (byte) 101) {
double a = ((System.currentTimeMillis() - peer.lastPinged) / 10.);
double b = peer.ping * 9 / 10.;
double c = a + b;
peer.ping = c;
// System.out.println("ping: " + (System.currentTimeMillis() - peer.lastPinged) + " avg.: " + Math.round(c*100)/100.);
return 1;
} else if (command == (byte) 100) {
// System.out.println("Antworte auf ping...");
// ByteBuffer allocate = ByteBuffer.allocate(1);
// allocate.put((byte) 101);
// allocate.flip();
// try {
// peer.getSocketChannel().write(allocate);
// } catch (IOException ex) {
// Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
// }
peer.writeBufferLock.lock();
writeBuffer.put((byte) 101);
peer.writeBufferLock.unlock();
peer.setWriteBufferFilled();
return 1;
} else if (command == (byte) 254) {
System.out.println("closing, other side init it...");
peer.disconnect("closing, other side init it...");
return 1;
}
byte nextByte = 0;
if (readBuffer.hasRemaining()) {
nextByte = readBuffer.get();
}
System.out.println(
"Wrong protocol, disconnecting + removing peer, nonce: " + peer.nonce + " Command was: " + command + " next byte: " + nextByte + " remaining: " + readBuffer.remaining() + " crypt-Stauts: out: " + (peer.writeBufferCrypted != null) + ", in: " + (peer.readBufferCrypted != null));
ByteBuffer a = ByteBuffer.allocate(1);
a.put(
(byte) 255);
a.flip();
try {
int write = peer.getSocketChannel().write(a);
System.out.println("QUIT bytes: " + write);
} catch (IOException ex) {
} catch (java.nio.channels.NotYetConnectedException e) {
}
//System.out.println("closing, got panic command...");
peer.disconnect(
"WRONG BYTE!");
//TODO add again
Test.removePeer(peer);
return 0;
}
public static void syncMessagesBack(final long time, final Peer peer, final int cnt) {
new Thread() {
@Override
public void run() {
long oldestTime = time;
Log.put("!BACK! sync... from: " + time, 20);
ResultSet executeQuery = MessageHolder.getMessagesForBackSync(time, cnt);
Log.put("query okay...", 20);
try {
while (executeQuery.next()) {
if (!peer.isConnected() || !peer.isAuthed()) {
break;
}
//System.out.println("sending message...");
int message_id = executeQuery.getInt("message_id");
int pubkey_id = executeQuery.getInt("pubkey_id");
byte[] bytes = executeQuery.getBytes("pubkey");
ECKey ecKey = new ECKey(null, bytes);
ecKey.database_id = pubkey_id;
byte public_type = executeQuery.getByte("public_type");
long timestamp = executeQuery.getLong("timestamp");
int nonce = executeQuery.getInt("nonce");
byte[] signature = executeQuery.getBytes("signature");
byte[] content = executeQuery.getBytes("content");
boolean verified = executeQuery.getBoolean("verified");
RawMsg m = new RawMsg(timestamp, nonce, signature, content, verified);
m.database_Id = message_id;
m.key = ecKey;
m.public_type = public_type;
// list.add(rawMsg);
if (!m.verified) {
continue;
}
boolean breakLoop = false;
while (!breakLoop) {
if (!peer.isConnected() || !peer.isAuthed()) {
break;
}
int size = 0;
peer.writeBufferLock.lock();
size = peer.writeBuffer.position();
peer.writeBufferLock.unlock();
if (size > 1500) {
System.out.println("writeBuffer position: " + size + " ip: " + peer.ip);
//peer.setWriteBufferFilled();
try {
sleep(100);
System.out.println("SLEEP");
} catch (InterruptedException ex) {
Logger.getLogger(ConnectionHandler.class
.getName()).log(Level.SEVERE, null, ex);
}
} else {
breakLoop = true;
}
}
//write Message to sync data.
Test.messageStore.addMessageToSendToSpecificPeer(message_id, peer.getPeerTrustData().internalId);
peer.writeMessage(m);
peer.setWriteBufferFilled();
//if (m.timestamp < oldestTime) {
oldestTime = m.timestamp;
//}
Log.put("back sync one message.....!!! sleep!" + " msgid: " + message_id, 1);
}
peer.writeBufferLock.lock();
if (peer.writeBuffer == null) {
return;
}
peer.writeBuffer.put((byte) 71);
peer.writeBuffer.putLong(oldestTime);
peer.writeBufferLock.unlock();
peer.setWriteBufferFilled();
} catch (SQLException ex) {
Logger.getLogger(ConnectionHandler.class
.getName()).log(Level.SEVERE, null, ex);
} finally {
if (peer.writeBufferLock.isHeldByCurrentThread()) {
peer.writeBufferLock.lock();
}
}
Log.put("finish!!!!!", 20);
}
}.start();
}
public static void syncAllMessagesSince(final long time, final Peer peer) {
new Thread() {
@Override
public void run() {
final String orgName = Thread.currentThread().getName();
if (!orgName.contains(" ")) {
Thread.currentThread().setName(orgName + " - syncMessages");
}
setPriority(MIN_PRIORITY);
int msgsWithoutCPUcheck = 0;
boolean MXBeanSupported = true;
try {
Class.forName("java.lang.management.ManagementFactory");
} catch (ClassNotFoundException e) {
MXBeanSupported = false;
}
try {
//currenlty sync 300 msg not more per connection establishment.!
int cntRows = -1;
while (cntRows == -1) {
// if (Settings.SUPERNODE) {
// time = 0;
// }
Log.put("full sync... from: " + time, 20);
ResultSet executeQuery = MessageHolder.getAllMessages(time, Long.MAX_VALUE, peer.getPeerTrustData().internalId);
Log.put("query okay...", 20);
// for (RawMsg m : MessageHolder.getAllMessages(time, System.currentTimeMillis())) {
cntRows = 0;
//// if (MXBeanSupported) {
////
//// ThreadMXBean tmb = ManagementFactory.getThreadMXBean();
////
//// long time = new Date().getTime() * 1000000;
//// long cput = 0;
//// double cpuperc = -1;
////
while (executeQuery.next()) {
cntRows++;
msgsWithoutCPUcheck++;
//// //System.out.println("asdf");
////
//// while (msgsWithoutCPUcheck > 10) {
//// msgsWithoutCPUcheck = 0;
//// if (tmb.isThreadCpuTimeSupported()) {
//// if (new Date().getTime() * 1000000 - time > 1000000000) { //Reset once per second
//// time = new Date().getTime() * 1000000;
//// //cput = tmb.getCurrentThreadCpuTime();
//// cput = getTotalCpuTime(tmb);
//// }
////
//// if (!tmb.isThreadCpuTimeEnabled()) {
//// tmb.setThreadCpuTimeEnabled(true);
//// }
////
//// if (new Date().getTime() * 1000000 - time != 0) {
//// //cpuperc = (tmb.getCurrentThreadCpuTime() - cput) / (new Date().getTime() * 1000000.0 - time) * 100.0;
//// cpuperc = (getTotalCpuTime(tmb) - cput) / (new Date().getTime() * 1000000.0 - time) * 100.0;
//// }
//// }
//// //System.out.println("checking...");
////
//////If cpu usage is greater then 50%
//// if (cpuperc > 20.0) {
//// try {
//// //sleep for a little bit.
//// //System.out.println("sleeping," + peer.ip + " msg id: " + executeQuery.getInt("message_id"));
//// sleep(200);
////
//// } catch (InterruptedException ex) {
//// Logger.getLogger(ConnectionHandler.class
//// .getName()).log(Level.SEVERE, null, ex);
//// }
//// //System.out.println("sleeeped");
//// continue;
//// } else {
//// break;
//// }
//// }
if (!peer.isConnected() || !peer.isAuthed()) {
break;
}
//System.out.println("sending message...");
int message_id = executeQuery.getInt("message_id");
//System.out.println("Have to send message: " + peer.ip + " - " + message_id);
// if (peer.getSendMessages().contains(message_id)) {
// continue;
// }
int pubkey_id = executeQuery.getInt("pubkey_id");
byte[] bytes = executeQuery.getBytes("pubkey");
ECKey ecKey = new ECKey(null, bytes);
ecKey.database_id = pubkey_id;
byte public_type = executeQuery.getByte("public_type");
long timestamp = executeQuery.getLong("timestamp");
int nonce = executeQuery.getInt("nonce");
byte[] signature = executeQuery.getBytes("signature");
//byte[] content = executeQuery.getBytes("content"); CONTENT ISNT AVAILABLE!! WE DONT NEED THE CONTENT
boolean verified = executeQuery.getBoolean("verified");
RawMsg m = new RawMsg(timestamp, nonce, signature, null, verified); //CONTENT IS NOT NEEDED!!
m.database_Id = message_id;
m.key = ecKey;
m.public_type = public_type;
// list.add(rawMsg);
if (!m.verified) {
continue;
}
boolean breakLoop = false;
while (!breakLoop) {
if (!peer.isConnected() || !peer.isAuthed()) {
break;
}
int used = 0;
peer.writeBufferLock.lock();
if (peer.writeBuffer == null) {
peer.writeBufferLock.unlock();
return;
}
used = peer.writeBuffer.position();
peer.writeBufferLock.unlock();
if (used > 2000) {
//System.out.println("SLEEP writeBuffer position: " + used + " ip: " + peer.ip);
//peer.setWriteBufferFilled();
try {
sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ConnectionHandler.class
.getName()).log(Level.SEVERE, null, ex);
}
} else {
breakLoop = true;
}
}
peer.writeMessage(m);
Log.put("sync msg to node " + m.database_Id, 70);
peer.setWriteBufferFilled();
// System.out.println("send");
}
if (cntRows == 100) {
//we have to wait until the synced messages will be removed from database
try {
Log.put("we have to wait until the synced messages will be removed from database", 70);
sleep(10000);
} catch (InterruptedException e) {
}
}
//// } else {
////
//// if (executeQuery == null) {
//// return;
//// }
//// //no MXBean supported, like android
//// while (executeQuery.next()) {
////
//// if (!peer.isConnected() || !peer.isAuthed()) {
//// break;
//// }
////
//// cntRows++;
////
//// //System.out.println("sending message...");
//// int message_id = executeQuery.getInt("message_id");
////
//// int pubkey_id = executeQuery.getInt("pubkey_id");
//// byte[] bytes = executeQuery.getBytes("pubkey");
//// ECKey ecKey = new ECKey(null, bytes);
//// ecKey.database_id = pubkey_id;
////
//// byte public_type = executeQuery.getByte("public_type");
//// long timestamp = executeQuery.getLong("timestamp");
//// int nonce = executeQuery.getInt("nonce");
//// byte[] signature = executeQuery.getBytes("signature");
//// byte[] content = executeQuery.getBytes("content");
//// boolean verified = executeQuery.getBoolean("verified");
//// RawMsg m = new RawMsg(timestamp, nonce, signature, content, verified);
//// m.database_Id = message_id;
//// m.key = ecKey;
//// m.public_type = public_type;
//// // list.add(rawMsg);
////
//// if (!m.verified) {
//// continue;
//// }
////
//// boolean breakLoop = false;
////
//// while (!breakLoop) {
////
//// if (!peer.isConnected() || !peer.isAuthed()) {
//// break;
//// }
////
//// int size = 0;
//// peer.writeBufferLock.lock();
//// size = peer.writeBuffer.position();
//// peer.writeBufferLock.unlock();
//// if (size > 200) {
//// System.out.println("writeBuffer position: " + size + " ip: " + peer.ip);
//// //peer.setWriteBufferFilled();
//// try {
//// sleep(100);
//// System.out.println("SLEEP");
////
//// } catch (InterruptedException ex) {
//// Logger.getLogger(ConnectionHandler.class
//// .getName()).log(Level.SEVERE, null, ex);
//// }
//// } else {
//// breakLoop = true;
//// }
////
//// }
//// peer.writeMessage(m);
//// peer.setWriteBufferFilled();
////// System.out.println("send");
////
//// }
////
//// }
////
}
} catch (SQLException ex) {
Logger.getLogger(ConnectionHandler.class
.getName()).log(Level.SEVERE, null, ex);
}
Log.put("finish", 20);
}
private long getTotalCpuTime(ThreadMXBean tmb) {
long[] allThreadIds = tmb.getAllThreadIds();
//System.out.println("Total JVM Thread count: " + allThreadIds.length);
long nano = 0;
for (long id : allThreadIds) {
nano += tmb.getThreadCpuTime(id);
}
return nano;
}
}.start();
}
void addServerSocketChannel(ServerSocketChannel serverSocketChannel) {
try {
selector.wakeup();
SelectionKey key = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
selector.wakeup();
System.out.println("added ServerSocketChannel");
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class
.getName()).log(Level.SEVERE, null, ex);
}
}
public String readString(ByteBuffer byteBuffer, int length) {
if (byteBuffer.limit() - byteBuffer.arrayOffset() < length) {
return null; //not enough bytes rdy!
}
byteBuffer.position(byteBuffer.position() + length);
return new String(byteBuffer.array(), byteBuffer.arrayOffset(), length);
}
private void sendHeader(Peer peer) {
ByteBuffer writeBuffer = peer.writeBuffer;
peer.writeBufferLock.lock();
writeBuffer.put(Test.MAGIC.getBytes());
writeBuffer.put((byte) Test.VERSION);
writeBuffer.putLong(Test.NONCE);
putUnsignedShot(writeBuffer, Test.MY_PORT);
peer.writeBufferLock.unlock();
}
// public void sendString(ByteBuffer byteBuffer, String string) {
// byteBuffer.put(string.getBytes());
// }
public void putUnsignedShot(ByteBuffer b, int unsignedShort) {
b.put(ByteUtils.intToUnsignedShortAsBytes(unsignedShort));
}
public int readUnsignedShort(ByteBuffer byteBuffer) {
byte[] toParse = new byte[2];
byteBuffer.get(toParse);
return ByteUtils.bytesToUnsignedShortAsInt(toParse, 0);
}
// private void closeConnection(Peer peer, SelectionKey key) throws IOException {
// peer.setConnected(false);
// key.cancel();
// peer.getSocketChannel().close();
// }
public static void closeAllSockets() {
ArrayList<Socket> a = allSockets;
allSockets = new ArrayList<Socket>();
int cnt = 0;
int closed = 0;
for (Socket s : a) {
cnt++;
if (s.isClosed()) {
closed++;
}
try {
s.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
System.out.println("closed " + cnt + " sockets, already closed " + closed);
}
public static void removeUnusedSockets() {
if (Test.getClonedPeerList() == null) {
return;
}
ArrayList<Socket> toRemove = new ArrayList<Socket>();
System.out.println("clean sockets: " + allSockets.size());
synchronized (allSockets) {
for (Socket socket : allSockets) {
boolean found = false;
for (Peer peer : Test.getClonedPeerList()) {
if (peer == null) {
Main.sendBroadCastMsg("null peer in list? 95178");
continue;
}
SocketChannel socketChannel = peer.getSocketChannel();
if (socketChannel == null) {
continue;
}
if (socket.equals(socketChannel.socket())) {
found = true;
break;
}
}
if (!found) {
if (socket.isClosed()) {
Log.put("found socket, which was not closed", 200);
} else {
Log.put("found closed socket", 200);
}
try {
//socket isnt used by any Peer, can be closed and removed.
socket.close();
} catch (IOException ex) {
}
toRemove.add(socket);
}
}
allSockets.removeAll(toRemove);
}
}
}